package com.zx.idc.backend.gui.scheduler.ins.accesslog;

import com.mongodb.BasicDBObject;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.IndexModel;
import com.zx.idc.common.lang.ListUtil;
import com.zx.idc.common.util.DateFormatterStringEnum;
import com.zx.idc.common.util.LocalDateTimeFormatUtil;
import com.zx.idc.ds.base.house.service.IBaseHouseInfoService;
import com.zx.idc.ds.httplog.entity.AccessLog;
import org.bson.Document;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Indexed;

import java.lang.reflect.Field;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.zx.idc.common.constants.CommonConstant.MONGODB_ACCESSLOG_DAYCOL_NAME_TEMPLATE;

/**
 * 创建具有索引的访问日志集合job(创建明天的)
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class CreateIndexCollectionOfAccessLogJob implements Job {

    private static final Logger LOG = LoggerFactory.getLogger(CreateIndexCollectionOfAccessLogJob.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IBaseHouseInfoService iBaseHouseInfoService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //获取机房列表
        try {
            LOG.info("创建访问日志集合job执行");
            List<Long> houseIds = iBaseHouseInfoService.selectListReturnId();
            if (ListUtil.isNotEmpty(houseIds)) {
                List<String> collectionNames = getCollectionName(houseIds);
                //集合的名称格式{acclog_{机房名称}_{yyyyHHdd}}
                //获取需要创建索引的参数列表
                Field[] declaredFields = AccessLog.class.getDeclaredFields();
                List<String> fieldNames = new ArrayList<>();
                for (Field field : declaredFields) {
                    if (field.getAnnotation(Indexed.class) != null) {
                        fieldNames.add(field.getName());
                    }
                }
                if (ListUtil.isNotEmpty(fieldNames)) {
                    //获取索引的模型
                    List<IndexModel> indexModels = getIndexModel(fieldNames);
                    for (String collectionName : collectionNames) {
                        MongoCollection<Document> collection = mongoTemplate.createCollection(collectionName);
                        collection.createIndexes(indexModels);
                    }
                }

            }
            LOG.info("创建访问日志集合job执行成功");
        } catch (Exception e) {
            LOG.error("创建访问日志集合job执行异常", e);
        }


    }

    /**
     * 返回索引列表
     *
     * @param fieldNames
     * @return
     */
    private List<IndexModel> getIndexModel(List<String> fieldNames) {
        return fieldNames.stream().map(fieldName -> new IndexModel(new BasicDBObject(fieldName, 1))).collect(Collectors.toList());
    }

    /**
     * 获取集合名称列表(时间是明天的) {acclog_{机房ID}_{yyyyHHdd}}
     *
     * @param houseIds
     * @return
     */
    private List<String> getCollectionName(List<Long> houseIds) {
        //获取明天时间字符串
        String dateStr = getTomorrowDateStr();
        return houseIds.stream()
            .map(id -> String.format(MONGODB_ACCESSLOG_DAYCOL_NAME_TEMPLATE, id, dateStr))
            .collect(Collectors.toList());
    }

    /**
     * 返回明天的时间字符串,格式为:yyyyHHdd
     *
     * @return
     */
    private String getTomorrowDateStr() {
        LocalDate localDate = LocalDate.now().plusDays(1L);
        return LocalDateTimeFormatUtil.formatLocalDate(localDate, DateFormatterStringEnum.YYYY_MM_DD);
    }


}
